type IdHubCallback = (
  key: string,
  value: string,
  type: 'layer' | 'source',
) => string;
// TODO 使用Map替代Record保证遍历顺序,以及constructor中参数
class IdHub {
  private _layers: Map<string, string>;
  private _sources: Map<string, string>;
  private _callback?: IdHubCallback;

  constructor(initialData?: {
    layers?: Record<string, string>;
    sources?: Record<string, string>;
  }) {
    this._layers = new Map(Object.entries(initialData?.layers || {}));
    this._sources = new Map(Object.entries(initialData?.sources || {}));

    // 返回 Proxy 代理实例
    // biome-ignore lint/correctness/noConstructorReturn: off
    return new Proxy(this, {
      get: (target, prop: string) => {
        // 1. 优先检查 layers 和 sources
        if (target._layers.has(prop)) return target._layers.get(prop);
        if (target._sources.has(prop)) return target._sources.get(prop);
        // 2. 默认行为（访问类方法或属性）
        return Reflect.get(target, prop);
      },
      set: (target, prop: string, value: string | IdHubCallback) => {
        if (prop === '_callback') {
          target._callback = value as IdHubCallback;
          return true;
        }
        // 允许内部方法修改_layers和_sources
        if (prop === '_layers' || prop === '_sources') {
          const newValue = value as string;
          // 同时更新对应的Record对象
          const record = target[prop];
          record.forEach((_, key) => {
            record.set(key, newValue);
          });
          return true;
        }
        // 禁止动态添加其他属性
        throw new Error(
          `Cannot dynamically add property '${prop}'. Use addLayer/addSource methods.`,
        );
      },
    }) as this; // 类型断言保留 this 类型
  }

  // 动态添加或更新 layers/sources 属性
  addLayer(key: string, value: string): void {
    this._layers.set(
      key,
      this._callback ? this._callback(key, value, 'layer') : value,
    );
  }

  addSource(key: string, value: string): void {
    this._sources.set(
      key,
      this._callback ? this._callback(key, value, 'source') : value,
    );
  }

  updateIds(
    callback: (key: string, value: string, type: 'layer' | 'source') => string,
  ): void {
    this._callback = callback;
    // 更新layers
    this._layers.forEach((value, key) => {
      this._layers.set(key, callback(key, value, 'layer'));
    });

    // 更新sources
    this._sources.forEach((value, key) => {
      this._sources.set(key, callback(key, value, 'source'));
    });
  }

  // 便捷访问方法：通过统一入口获取值
  get(key: string, type: 'layer' | 'source'): string | undefined {
    return type === 'layer' ? this._layers.get(key) : this._sources.get(key);
  }

  getLayerId(key: string): string {
    return this._layers.get(key) || '';
  }

  getSourceId(key: string): string {
    return this._sources.get(key) || '';
  }

  // 批量设置（可选）
  setLayers(data: Record<string, string>): void {
    Object.entries(data).forEach(([key, value]) => {
      this._layers.set(key, value);
    });
  }

  setSources(data: Record<string, string>): void {
    Object.entries(data).forEach(([key, value]) => {
      this._sources.set(key, value);
    });
  }

  // 获取全部属性（可选）
  getAllLayers(): Record<string, string> {
    return Object.fromEntries(this._layers);
  }

  getAllSources(): Record<string, string> {
    return Object.fromEntries(this._sources);
  }

  getAllLayersIdList(): string[] {
    return [...this._layers.values()];
  }

  getAllSourcesIdList(): string[] {
    return [...this._sources.values()];
  }
}

export type IdHubType = {
  [key: string]: string;
} & IdHub; // 显式交叉类型

export default IdHub;
